package es_deusto_engineering_IS_HanoiTower;

import es.deusto.ingenieria.is.search.formulation.Operator;
import es.deusto.ingenieria.is.search.formulation.State;

public class Action extends Operator{
	private int toPeg;
	private int fromPeg;
	//All the actions have the same cost
	final static double cost = 1;
	
	/**This method receives a String from which the origin (fromPeg) and destination (toPeg) pegs of the movement are
	 * splitted.
	 * @param name
	 */
	public Action(String name)
	{
		super(name,1d);
		String[] divided = name.split(" ");
		this.fromPeg = Integer.parseInt(divided[1]);
		this.toPeg = Integer.parseInt(divided[3]);

		
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	@Override
	protected State effect(State e) {
		
	    //we need to clone the environment not to make changes on the Environment we pass from the method (State e)
		Environment envi = ((Environment)e).clone();
		
		//We take the origin peg from the environment
		Peg origPeg = ((Environment)envi).getPegs().get(fromPeg);
		
		//check if there are disks on the from peg
		if(!origPeg.getDisks().isEmpty())
		{
			//take the disk from the top of from Peg and delete the disk from this peg
			Disk d1 = origPeg.removeDisk();

			//we take the destination peg from the environment
			Peg destPeg = ((Environment)envi).getPegs().get(toPeg);
			//We enter the disk on the top of the destination peg by using the push method
			destPeg.addDisk(d1);
			
			return envi;
		}
		
		return null;
	}

	@Override
	protected boolean isApplicable(State envi) {
		
		//we take the peg from where we want to take the disk
		Peg origPeg = ((Environment)envi).getPegs().get(fromPeg);
		
		//check if there are disks or not in the peg
		if(!origPeg.getDisks().isEmpty())
		{
			//take the disk of the top of fromPeg
			Disk d1 = origPeg.getDisks().lastElement();
			
			//we take the peg to which we want to add the disk
			Peg destPeg = ((Environment)envi).getPegs().get(toPeg);
			//if the toPeg is empty, the action is applicable and there is no problem with sizes.
			if(!destPeg.getDisks().isEmpty())
			{
				//if there are disks already introduced, we check their sizes
				Disk d2 = destPeg.getDisks().lastElement();
				//only if the disk we want to add is smaller
				if(d2.getSize() > d1.getSize())
					return true;
				else
					return false;
			}
			else
			{
					return true;
			}
			
		}
		else
		{
			return false;
		}
	}

}
